import cv2
import numpy as np
import torch
import torch.nn.functional as F

# 读取图像
img = cv2.imread('image.jpg')  # 确保该图像存在
cv2.imshow("Original Image", img)

# 1. OpenCV 双线性插值下采样
downsampled_bilinear = cv2.resize(img, (128, 128), interpolation=cv2.INTER_LINEAR)

# 2. OpenCV 双三次插值下采样
downsampled_bicubic = cv2.resize(img, (128, 128), interpolation=cv2.INTER_CUBIC)

# 3. OpenCV 邻近插值下采样
downsampled_nearest = cv2.resize(img, (128, 128), interpolation=cv2.INTER_NEAREST)

# 4. OpenCV 高斯金字塔降采样
downsampled_gaussian = cv2.pyrDown(img)  # 原图尺寸自动变为一半

# 5. PyTorch 最大池化（Max Pooling）
input_tensor = torch.tensor(img, dtype=torch.float32).permute(2, 0, 1).unsqueeze(0)  # [B, C, H, W]
downsampled_maxpool = F.max_pool2d(input_tensor, kernel_size=2, stride=2)

# 6. PyTorch 平均池化（Average Pooling）
downsampled_avgpool = F.avg_pool2d(input_tensor, kernel_size=2, stride=2)

# 7. PyTorch 跳采样卷积（Stride Convolution）
conv_weight = torch.ones(3, 3, 3, 3) / 9  # 简单的 3x3 平均滤波器
downsampled_stride_conv = F.conv2d(input_tensor, conv_weight, stride=2, padding=1)

# 8. 使用 NumPy 手动下采样（步长采样）
downsampled_numpy = img[::2, ::2, :]  # 每隔一个像素点取样

# 显示结果
cv2.imshow("Downsampled Bilinear", downsampled_bilinear)
cv2.imshow("Downsampled Bicubic", downsampled_bicubic)
cv2.imshow("Downsampled Nearest", downsampled_nearest)
cv2.imshow("Downsampled Gaussian", downsampled_gaussian)
cv2.imshow("Downsampled NumPy Stride", downsampled_numpy)

cv2.waitKey(0)
cv2.destroyAllWindows()
